package com.heima.leetcode.practice;

/**
 * @author 勾新杰
 * @version 1.0
 * @description: leetcode 8. 字符串转换整数
 * @date 2025/3/4 11:25
 */
public class E8 {

    /**
     * <h3>方法一：用long，但是当超过long的不行</h3>
     *
     * @param s 字符串
     * @return 整数
     */
    public int myAtoi1(String s) {
        Boolean positive = null;
        char[] charArray = s.toCharArray();
        long result = 0;
        boolean hasDigit = false;
        for (char c : charArray) {
            if (c == ' ') {
                if (!hasDigit) {
                    continue;
                } else {
                    break;
                }
            } else if (c == '+') {
                if (positive != null) break;
                if (hasDigit) break;
                positive = true;
            } else if (c == '-') {
                if (positive != null) break;
                if (hasDigit) break;
                positive = false;
            } else if (Character.isDigit(c)) {
                hasDigit = true;
                result = result * 10 + c - '0';
            } else {
                break;
            }
        }
        if (positive == null) positive = true;
        if (!positive && result - 1 >= Integer.MAX_VALUE) return Integer.MIN_VALUE;
        if (result > Integer.MAX_VALUE) result = Integer.MAX_VALUE;
        return positive ? (int) result : -(int) result;
    }

    /**
     * <h3>方法二：完美版本1，判断是否溢出可以查看leetcode7</h3>
     * @param s 字符串
     * @return 整数
     */
    @SuppressWarnings("all")
    public int myAtoi2(String s) {
        // 分别对应正负标志位，以及是否出现数字标志位，是否是正数
        boolean hasFlag = false, hasDigit = false, positive = true;
        char[] charArray = s.toCharArray();
        int result = 0;
        for (char c : charArray) {
            if (c == ' ') {
                // 如果已经出现数字或者正负标志位，则跳出循环
                if (hasDigit || hasFlag) break;
            } else if (c == '+') {
                // 如果没有出现符号标志位并且没有出现数字标志位，则设置正负标志位，进行下一次循环
                if (!hasFlag && !hasDigit) {
                    hasFlag = true;
                    positive = true;
                }
                // 如果已经出现数字或者正负标志位，则跳出循环
                else break;
            } else if (c == '-') {
                // 如果没有出现符号标志位并且没有出现数字标志位，则设置正负标志位，进行下一次循环
                if (!hasFlag && !hasDigit) {
                    hasFlag = true;
                    positive = false;
                }
                // 如果已经出现数字或者正负标志位，则跳出循环
                else break;
            } else if (Character.isDigit(c)) {
                // 如果出现数字，更新数字标志位
                hasDigit = true;
                // 如果该数是正数，先判断乘法的时候有没有溢出，再判断加法的时候有没有溢出
                if(positive && (result > Integer.MAX_VALUE / 10 || (result == Integer.MAX_VALUE / 10 && c - '0' > 7))) return Integer.MAX_VALUE;
                // 如果该数是负数，先判断乘法的时候有没有溢出，再判断加法的时候有没有溢出
                if(!positive && (result < Integer.MIN_VALUE / 10 || (result == Integer.MIN_VALUE / 10 && c - '0' > 8 ))) return Integer.MIN_VALUE;
                // 根据正负符号标志，选择如何进行加操作
                result = positive ? result * 10 + c - '0': result * 10 - c + '0';
            } else {
                // 遇到字母，直接跳出循环
                break;
            }
        }
        return result;
    }

    /**
     * <h3>方法三：完美版本2，判断是否溢出可以查看leetcode7</h3>
     * @param s 字符串
     * @return 整数
     */
    @SuppressWarnings("all")
    public int myAtoi3(String s) {
        boolean hasFlag = false, hasDigit = false, positive = true;
        char[] charArray = s.toCharArray();
        int result = 0;
        for (char c : charArray) {
            if (c == ' ') {
                if (hasDigit || hasFlag) break;
            } else if (c == '+') {
                if (!hasFlag && !hasDigit) {
                    hasFlag = true;
                    positive = true;
                }
                else break;
            } else if (c == '-') {
                if (!hasFlag && !hasDigit) {
                    hasFlag = true;
                    positive = false;
                }
                else break;
            } else if (Character.isDigit(c)) {
                hasDigit = true;
                if(positive && (result > Integer.MAX_VALUE / 10 || (result * 10 == Integer.MAX_VALUE - 7 && c - '0' > 7))) return Integer.MAX_VALUE;
                if(!positive && (result < Integer.MIN_VALUE / 10 || (result * 10 == Integer.MIN_VALUE + 8 && c - '0' > 8 ))) return Integer.MIN_VALUE;
                result = positive ? result * 10 + c - '0': result * 10 - c + '0';
            } else {
                break;
            }
        }
        return result;
    }

    public static void main(String[] args) {
        E8 e8 = new E8();
        System.out.println(Integer.MAX_VALUE / 10);
        System.out.println(e8.myAtoi2("2147483648"));
    }
}
